package com.webflux.controller;

import com.webflux.utils.SlideWindow;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author: 王霄
 * @date: 2022/1/14 9:38
 **/
@RestController
@RequestMapping("/web")
public class WebFluxController {

    private static final DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS");

    @GetMapping(value = "/mono")
    public Mono<String> mono() {
        return Mono.create(monoSink -> {
            //在onsuccess之前,Mono流并不会返回结果
            monoSink.success("发布数据1");
            monoSink.success("发布数据2");
            monoSink.success("发布数据3");
        });
    }

    @GetMapping(value = "/flux", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> flux() {
        //从0到100一秒钟发布一个数字
        return Flux.interval(Duration.ofSeconds(1))
                .limitRate(100)
                .map(String::valueOf);
    }


    /**
     * 限流测试接口
     *
     * @param count  发布指令的总数
     * @param period 周期
     * @param num    周期内发布指令的数量
     * @return
     */
    @GetMapping(value = "/limit/{count}/{period}/{num}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    private Flux<String> limit(@PathVariable int count,
                               @PathVariable long period,
                               @PathVariable int num) {
        SlideWindow window = new SlideWindow("test", period, num);
        return Flux.range(1, count)
                .map(x -> {
                    window.pass();
                    return String.format("%s 第%d/%d条指令发送成功", df.format(LocalDateTime.now()), x, count);
                });
    }
}
